using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace Nizm0.QOT.Library.Objects
{
    [Serializable]
    public class Project : Objects.ISettingsObjects
    {
        private bool _set;
        protected string _projectName;
        protected string _projectLocation;
        private string _projectResultsLocation;
        /// <summary>
        /// Project file name
        /// </summary>
        protected string _fileName;
        protected List<ObservedDirectory> _observedDirectories = new List<ObservedDirectory>();
        private DateTime _openDateTime;
        static protected string _projectExtension = ".qot";

        public delegate void ObservedDirectoryChangeEventHandler(string directory);
        public delegate void ObservedDirectoryChangeDirectoryEventHandler(string directoryOld, string directoryNew);
        public delegate bool ProjectLocationChangeEventHandler(Project project);

        //public delegate void ChangeStatusEvetHendler(String str);
        public event ChangeStatusEvetHendler StatusChange;

        //public delegate void OnErrorEventHandler(string str, Exception ex);
        public event ErrorEventHandler ErrorEvent;

        public event ObservedDirectoryChangeEventHandler ObservedDirectoryAdded;
        public event ObservedDirectoryChangeDirectoryEventHandler ObservedDirectoryChange;
        public event ObservedDirectoryChangeEventHandler ObservedDirectoryDeleted;
        public event ProjectLocationChangeEventHandler ProjectLocationChange;

        #region Propertiess

        [ReadOnlyAttribute(true)]
        public bool Set
        {
            get { return _set; }
        }
        public string ProjectName
        {
            get { return _projectName; }
            set { _projectName = value; _set = true; }
        }
        [ReadOnlyAttribute(true)]
        public string ProjectLocation
        {
            get { return _projectLocation; }
            set
            {
                _projectLocation = value;
                if (String.IsNullOrWhiteSpace(_fileName))
                    _fileName = _projectLocation + "\\" + _projectName + _projectExtension;
            }
        }
        public string ProjectResultsLocation
        {
            get
            {
                if (String.IsNullOrEmpty(_projectResultsLocation))
                    return _projectLocation + "\\Queries\\";
                else
                    return _projectResultsLocation;
            }
            set
            {
                if (value.EndsWith("\\"))
                    _projectResultsLocation = value;
                else
                    _projectResultsLocation = value + "\\";
            }
        }
        [ReadOnlyAttribute(true)]
        public string FileName
        {
            get { return _fileName; }
            set
            {
                _fileName = value;
                System.IO.FileInfo f = new System.IO.FileInfo(value);
                _projectLocation = f.DirectoryName;
            }
        }
        public List<ObservedDirectory> ObservedDirectories
        {
            get { return _observedDirectories; }
        }
        [DescriptionAttribute("Time when the project was open for the last time."),
        ReadOnlyAttribute(true),
        CategoryAttribute("Global Settings")/*,
        DefaultValueAttribute(10)*/]
        public DateTime OpenDateTime
        {
            get { return _openDateTime; }
            set { _openDateTime = value; }
        }
        [ReadOnlyAttribute(true)]
        public string ProjectExtension
        {
            get { return _projectExtension; }
        }
        //[ReadOnlyAttribute(true)]
        //static public string ProjectLocalization
        //{
        //    get
        //    {
        //        if (_programLocalization == null || _programLocalization == string.Empty)
        //            GetProgramLocalization();
        //        return _programLocalization;
        //    }
        //}
        #endregion

        #region Objects.ISettingsObjects Members

        string Objects.ISettingsObjects.Name
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        int Objects.ISettingsObjects.Treelevel
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        bool Objects.ISettingsObjects.Checked
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        [Obsolete("Is this being used?", false)]
        public Project(Project project)
        {
            _projectName = project.ProjectName;
            _projectLocation = project.ProjectLocation;
            _fileName = project.FileName;
            _openDateTime = project.OpenDateTime;
            _set = true;
            StatusChange = project.StatusChange;
            ErrorEvent = project.ErrorEvent;
        }

        public Project(string fileName)
        {
            _fileName = fileName;
            _projectName = ProjectSettings.Instance.ProjectName;
            _projectLocation = ProjectSettings.Instance.ProjectLocation;
            _openDateTime = ProjectSettings.Instance.OpenDateTime;
            _set = true;
        }

        public Project(string projectName, string projectLocation, DateTime openDateTime)
        {
            _projectName = projectName;
            _projectLocation = projectLocation;
            _fileName = _projectLocation + "\\" + _projectName + _projectExtension;
            _openDateTime = openDateTime;
            _set = true;
        }

        public Project()
        { }

        //static private void GetProgramLocalization()
        //{
        //    _programLocalization = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
        //}

        /// <summary>
        /// Add table of directory ass observed directories
        /// </summary>
        /// <param name="directory">Table of darectories</param>
        public void AddObservedDirectories(string[] directory)
        {
            if (directory.Length > 0)
                foreach (string dir in directory)
                    try
                    {
                        AddObservedDirectories(dir);
                    }
                    catch (System.IO.DirectoryNotFoundException ex)
                    {
                        System.Windows.Forms.MessageBox.Show(string.Format("Directory {0} not exists\n{1}", dir, ex.Message), "Warning!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                    }
        }
        /// <summary>
        /// Add list of directory ass dobserved directories
        /// </summary>
        /// <param name="directory">List of irectories</param>
        public void AddObservedDirectories(List<string> directory)
        {
            AddObservedDirectories(directory.ToArray());
        }
        /// <summary>
        /// Add directory ass observed directory
        /// </summary>
        /// <param name="directory">Directory to observe</param>
        public void AddObservedDirectories(string directory)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(directory))
                {
                    if (System.IO.Directory.Exists(directory))
                    {
                        OnObservedDirectoryAdded(directory);
                    }
                    else
                    {
                        OnObservedDirectoryAdded(directory);
                        throw new System.IO.DirectoryNotFoundException(String.Format("Location {0} not exists, or \"Access deny\"", directory));
                    }
                }
            }
            catch (System.IO.DirectoryNotFoundException exd)
            {
                System.Windows.Forms.MessageBox.Show(string.Format("Directory {0} not exists\n{1}", directory, exd.Message), "Warning!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString(), "Warning!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// Change observed directory
        /// </summary>
        /// <param name="fromdirectory">Directory to change</param>
        /// <param name="todirectory">New directory to observe</param>
        public void ChangeObservedDirectories(string fromdirectory, string todirectory)
        {
            if (!string.IsNullOrWhiteSpace(fromdirectory) && !string.IsNullOrWhiteSpace(todirectory))
            {
                if (System.IO.Directory.Exists(todirectory))
                {
                    if (ObservedDirectoryChange != null)
                    {
                        _observedDirectories.Find(d=>d.Directory==fromdirectory).Directory = todirectory;
                        ObservedDirectoryChange(fromdirectory, todirectory);
                    }
                }
                else
                    throw new System.IO.DirectoryNotFoundException(String.Format("Location {0} not exists", todirectory));
            }
        }
        /// <summary>
        /// Remowe table directory from observed list
        /// </summary>
        /// <param name="directory">Table of directories</param>
        public void RemoweObservedDirectories(string[] directory)
        {
            if (directory.Length > 0)
                foreach (string dir in directory)
                    RemoweObservedDirectories(dir);
        }
        /// <summary>
        /// Remowe list directory from observed list
        /// </summary>
        /// <param name="directory">List of directories</param>
        public void RemoweObservedDirectories(List<string> directory)
        {
            RemoweObservedDirectories(directory.ToArray());
        }
        /// <summary>
        /// Remowe directory from observed list
        /// </summary>
        /// <param name="directory">directory to remowe</param>
        public void RemoweObservedDirectories(string directory)
        {
            if (!string.IsNullOrWhiteSpace(directory))
            {
                if (_observedDirectories.Exists(d => d.Directory == directory))
                {
                    _observedDirectories.RemoveAll(d => d.Directory == directory);
                    ObservedDirectoryDeleted(directory);
                }
            }
        }
        /// <summary>
        /// Remowe list directory from observed list
        /// </summary>
        /// <param name="directory">List of directories</param>
        public void RemoweObservedDirectories(IEnumerable<string> directory)
        {
            RemoweObservedDirectories((List<string>)directory);
        }

        public bool OnProjectLocationChange(Project project)
        {
            if (ProjectLocationChange != null)
            {
                return ProjectLocationChange(project);

            }
            return false;
        }

        private void OnObservedDirectoryAdded(string directory)
        {
            if (ObservedDirectoryAdded != null && !_observedDirectories.Exists(d => d.Directory == directory))
            {
                _observedDirectories.Add(new ObservedDirectory(directory));
                ObservedDirectoryAdded(directory);
            }
        }
    }
}
